package com.zhoug.common3.adapters.recycler.dividers.sticky;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.View;

import com.zhoug.common3.utils.LogUtils;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 粘性标题基类 适用于{@link androidx.recyclerview.widget.LinearLayoutManager} 布局
 *
 * @Author 35574
 * @Date 2021/3/26
 * @Description
 */
public abstract class ListStickyDecoration<T> extends RecyclerView.ItemDecoration {
    private static final String TAG = ">>>ListStickyDecoration";
    private static final boolean DEBUG = false;
    private GroupInfoCallback<T> mGroupInfoCallback;
    private Rect mBounds = new Rect();
    private Rect mHeaderRect = new Rect();

    public ListStickyDecoration() {

    }

    /**
     * Header的高度
     *
     * @return
     */
    protected abstract int getHeaderHeight();

    /**
     * 绘制头部
     * @param canvas
     * @param headerRect 头部区局
     * @param groupInfo 头部数据
     */
    protected abstract void onDrawHeader(Canvas canvas, Rect headerRect, GroupInfo<T> groupInfo);


    /**
     * 通过该方法，在Canvas上绘制内容，在绘制Item之前调用。（如果没有通过getItemOffsets设置偏移的话，Item的内容会将其覆盖）
     *
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }


    /**
     * 通过该方法，在Canvas上绘制内容,在Item之后调用。(画的内容会覆盖在item的上层)
     *
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        drawHeader(c, parent, state);
    }


    /**
     * 绘制Header,
     * 粘性头部为第一个显示的Item的分组信息
     *
     * @param c
     * @param parent
     * @param state
     */
    private void drawHeader(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int childCount = parent.getChildCount();
        if (childCount > 0) {
            int headerHeight = getHeaderHeight();
            //粘性头部组内的最后一个Item的index,用第一个非粘性头部的index-1
            int groupLastIndex = -1;
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                //child在Adapter中的位置
                int position = parent.getChildAdapterPosition(child);
                //绘制非粘性header
                if (i != 0 && isDrawHeader(position)) {
                    if (groupLastIndex == -1) {
                        groupLastIndex = i - 1;
                    }
                    parent.getDecoratedBoundsWithMargins(child, mBounds);
                    if (DEBUG) {
                        LogUtils.d(TAG, position + ":" + mBounds);
                    }
                    mHeaderRect.left = parent.getPaddingStart();
                    mHeaderRect.top = mBounds.top;
                    mHeaderRect.right = parent.getWidth() - parent.getPaddingEnd();
                    mHeaderRect.bottom = mHeaderRect.top + headerHeight;
                    onDrawHeader(c, mHeaderRect, mGroupInfoCallback.getGroupInfo(position));
                }
            }

            //绘制悬停顶部的header
            //屏幕上第一个可见Item
            View firstVisibilityItem = parent.getChildAt(0);
            int position = parent.getChildAdapterPosition(firstVisibilityItem);
            mHeaderRect.left = parent.getPaddingStart();
            mHeaderRect.top = parent.getPaddingTop();
            mHeaderRect.bottom = mHeaderRect.top + headerHeight;
            mHeaderRect.right = parent.getWidth() - parent.getPaddingEnd();
            if (groupLastIndex >= 0) {
                //粘性头部组内最后一个Item
                final View childLast = parent.getChildAt(groupLastIndex);
                parent.getDecoratedBoundsWithMargins(childLast, mBounds);
                //如果粘性头部的底部和组内最后一个Item的底部对齐则到了上推的临界点
                //头部需要跟随最后一个Item移动出屏幕
                if (mBounds.bottom <= parent.getPaddingTop()+headerHeight) {
                    mHeaderRect.bottom = mBounds.bottom;
                    mHeaderRect.top = mHeaderRect.bottom - headerHeight;
                }
            }

            onDrawHeader(c, mHeaderRect, mGroupInfoCallback.getGroupInfo(position));
        }
    }


    /**
     * 通过Rect为每个Item设置偏移，用于绘制Decoration。
     *
     * @param outRect
     * @param view
     * @param parent
     * @param state
     */
    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
//        super.getItemOffsets(outRect, view, parent, state);
        int pos = parent.getChildAdapterPosition(view);
        if (isDrawHeader(pos)) {
            outRect.top = getHeaderHeight();
        }
    }





    /**
     * 是否需要画Header
     *
     * @param position
     * @return
     */
    private boolean isDrawHeader(int position) {
        if (mGroupInfoCallback != null) {
            if (position == 0) {
                return true;
            }
            GroupInfo<T> groupInfo1 = mGroupInfoCallback.getGroupInfo(position);
            GroupInfo<T> groupInfo2 = mGroupInfoCallback.getGroupInfo(position - 1);

            boolean equals = !groupInfo1.getGroupId().equals(groupInfo2.getGroupId());
            if (DEBUG) {
                LogUtils.d(TAG, "isDrawHeader:"+position+"=>"+equals);
            }
            return equals;
        }
        return false;
    }


    public void setGroupInfoCallback(GroupInfoCallback<T> groupInfoCallback) {
        this.mGroupInfoCallback = groupInfoCallback;
    }





}
